package GameEngine;

import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.Action;
import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;

/**
 * Maps the player's controls to actions
 * @author WhateverWillIDo
 *
 */
public class InputMap {

    private KeyStroke up = KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false);
    private KeyStroke left = KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, false);
    private KeyStroke right = KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, false);
    private KeyStroke special = KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, false);
    private KeyStroke releasedLeft = KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, true);
    private KeyStroke releasedRight = KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, true);
    private KeyStroke releasedUp = KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, true);
    private JComponent component;
    private boolean isLeft = false;
    private boolean isRight = false;
    private boolean isUp = false;
    private Client user;

    /**
     * A constructor;
     * @param comp  JComponent where one wishes to place the map
     * @param u     The user instance that will send out the input to the server
     */
    public InputMap(JComponent comp, Client u)
    {
        component = comp;
        user = u;

        component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(up, "up");
        component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(left, "left");
        component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(right, "right");
        component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(special, "special");
        component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(releasedLeft, "released left");
        component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(releasedRight, "released right");
        component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(releasedUp, "released up");

        component.getActionMap().put("up", actionUp);
        component.getActionMap().put("left", actionLeft);
        component.getActionMap().put("right", actionRight);
        component.getActionMap().put("special", actionSpecial);
        component.getActionMap().put("released left", actionRLeft);
        component.getActionMap().put("released right", actionRRight);
        component.getActionMap().put("released up", actionRUp);
    }

    public void setUp(KeyStroke k) {
        component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).clear();
        component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(k, "up");
        component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(k.getKeyCode(), 0, true), "released up");
    }

    public void setLeft(KeyStroke k) {
        component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).clear();
        component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(k, "left");
        component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(k.getKeyCode(), 0, true), "released left");
    }

    public void setRight(KeyStroke k) {
        component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).clear();
        component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(k, "right");
        component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(k.getKeyCode(), 0, true), "released right");
    }

    public void setSpecial(KeyStroke k) {
        component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).clear();
        component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(k, "special");
    }
    Action actionUp = new AbstractAction() {

        public void actionPerformed(ActionEvent e) {
            user.writeAction(GameConstants.Action.JUMP);
            isUp = true;

            if (isLeft) {
                user.writeAction(GameConstants.Action.MOVELEFT);
            } else if (isRight) {
                user.writeAction(GameConstants.Action.MOVERIGHT);
            }

            
        }
    };
    Action actionLeft = new AbstractAction() {

        public void actionPerformed(ActionEvent e) {
            isLeft = true;
            user.writeAction(GameConstants.Action.MOVELEFT);
            if (isUp) {
                user.writeAction(GameConstants.Action.JUMP);
                isUp = false;
            }
        }
    };
    Action actionRight = new AbstractAction() {

        public void actionPerformed(ActionEvent e) {

            isRight = true;
            user.writeAction(GameConstants.Action.MOVERIGHT);

            if (isUp) {
                user.writeAction(GameConstants.Action.JUMP);
                isUp = false;
            }
        }
    };
    Action actionSpecial = new AbstractAction() {

        public void actionPerformed(ActionEvent e) {
            user.writeAction(GameConstants.Action.USESPECIAL);
        }
    };
    Action actionRLeft = new AbstractAction() {

        public void actionPerformed(ActionEvent e) {
            isLeft = false;
        }
    };
    Action actionRRight = new AbstractAction() {

        public void actionPerformed(ActionEvent e) {
            isRight = false;
        }
    };
    Action actionRUp = new AbstractAction() {

        public void actionPerformed(ActionEvent e) {
            isUp = false;
        }
    };
}
